Usually, you do not need to worry about allocating memory for sound channels because the SndNewChannel function automatically allocates a sound channel record in the application's heap if passed a pointer to a NIL sound channel. SndNewChannel also internally allocates memory for the sound channel's queue of sound commands. For example, the following lines of code request that the Sound Manager open a new sound channel for playing sampled sounds:
mySndChan := NIL;
myErr := SndNewChannel(mySndChan, sampledSynth, 0, NIL);
If you are concerned with managing memory yourself, you can allocate your own memory for a sound channel record and pass the address of that memory as the first parameter to SndNewChannel . By allocating a sound channel record manually, you not only obtain control over the allocation of the sound channel record, but you can specify the size of the queue of sound commands that the Sound Manager internally allocates. Listing 1-11 illustrates one way to do this.
Listing 11 Creating a sound channel
FUNCTION MyCreateSndChannel (synth: Integer; initOptions: LongInt;
userRoutine: ProcPtr;
queueLength: Integer): SndChannelPtr;
VAR
mySndChan: SndChannelPtr; {pointer to a sound channel}
myErr: OSErr;
BEGIN
{Allocate memory for sound channel.}
mySndChan := SndChannelPtr(NewPtr(Sizeof(SndChannel)));
IF mySndChan <> NIL THEN
BEGIN
mySndChan^.qLength := queueLength; {set number of commands in queue}
{Create a new sound channel.}
myErr := SndNewChannel(mySndChan, synth, initOptions, userRoutine);
IF myErr <> noErr THEN
BEGIN {couldn't allocate channel}
DisposePtr(Ptr(mySndChan)); {free memory already allocated}
mySndChan := NIL; {return NIL}
END
ELSE
mySndChan^.userInfo := 0; {reset userInfo field}
END;
MyCreateSndChannel := mySndChan; {return new sound channel}
END;
The MyCreateSndChannel function defined in Listing 1-11 first allocates memory for a sound channel record and then calls the SndNewChannel function to attempt to allocate a channel. Note that MyCreateSndChannel checks the result code returned by SndNewChannel to determine whether the function was able to allocate a channel. The SndNewChannel function might not be able to allocate a channel if there are so many channels open that allocating another would put too much strain on the CPU. Also, SndNewChannel might fail if memory is low. (In addition to the memory for a sound channel record that is passed in the first parameter to SndNewChannel , the function must internally allocate memory in which to store sound commands.)
If you allocate memory for a sound channel record, you should specify the size of the queue of sound commands by assigning a value to the qLength field of the sound channel record you allocate. You can use the constant stdQLength to obtain a standard queue of 128 sound commands, or you can provide a value of your own.
CONST
stdQLength = 128; {default size of a sound channel}
If you know that your application will play only resources containing sampled sound, you might set the qLength field to a considerably lower value, because resources created with the SndRecord function (described in the chapter "Introduction to Sound on the Macintosh" in this book) contain only one sound command, the bufferCmd command, which specifies that a buffer of sound should be played. For example, if your application uses a sound channel only to play a single sampled sound asynchronously, you can set qLength to 2, to allow for the bufferCmd command and a callBackCmd command that your application issues manually, as described in "Playing Sounds Asynchronously" . By using a smaller than standard queue length, your application can conserve memory.
The number of sound commands in a channel should be an integer greater than 0. If you open a channel with a 0-length queue, most of the Sound Manager routines will return a badChannel result code.
In general, however, you should let the Sound Manager allocate sound channel records for you. The amount of memory you might save by allocating your own is usually negligible.
The second parameter in the SndNewChannel function specifies the kind of data you want to play on that channel. You can specify one of the following constants:
CONST
squareWaveSynth = 1; {square-wave data}
waveTableSynth = 3; {wave-table data}
sampledSynth = 5; {sampled-sound data}
In some versions of system software prior to system software version 7.0 (including system software version 6.0.7), high-level Sound Manager routines do not work properly with sound resources that specify the sound data type twice. This might happen if a resource specifies that a sound consists of sampled-sound data and an application does the same when creating a sound channel. This might also happen if an application uses the same sound channel to play several sound resources that contain different kinds of sound data. There are several solutions to this problem that you can use if you must maintain compatibility with old versions of system software:
Note that this problem does not occur with sound files, because sound files always contain sampled-sound data and thus do not explicitly declare their data type. As a result, when creating a channel in which you plan to play a sound file, pass sampledSynth as the second parameter to SndNewChannel .
The third parameter in the SndNewChannel function specifies the initialization parameters to be associated with the new channel. These are discussed in the following section. The fourth parameter in the SndNewChannel function is a pointer to a callback procedure. If your application produces sounds asynchronously or needs to be alerted when a command has completed, you can specify a callback procedure by passing the address of that procedure in the fourth parameter and then by installing a callback procedure into the sound channel. If you pass NIL as the fourth parameter, then no callback procedure is associated with the channel. See "Playing Sounds Asynchronously" for more information on setting up and using callback procedures.
| Previous | Chapter contents | Chapter top | Section top | Next |